home *** CD-ROM | disk | FTP | other *** search
- #include "util.h"
- #include "mmdf.h"
- #include "cmd.h"
- #include "ch.h"
- #include "dm.h"
- #include "ap.h"
-
- /*
- * This module applies authorization on the basis of channel
- * sending host, receiving host, sender, and recipient.
- *
- * Initial coding Steve Kille. Jan 84
- */
-
- extern struct ll_struct *logptr;
-
- extern long tx_msize;
- extern int adruid;
-
- extern char *authfile; /* file with warning message */
- extern char *authrequest; /* where to send error request to */
-
- extern char *locdomain;
- extern char *locname;
- extern char *adr_fulldmn;
- extern char *supportaddr;
- extern char *mgt_return;
-
- Table *authtable;
-
- char auth_msg [LINESIZE*2];
-
- /* space for auth error message */
- /* to be passed upwards by submit */
- extern char *logdfldir;
-
- extern struct ll_struct authlog;
- struct ll_struct *alogptr = &authlog;
-
- char *user_string = "username";
-
- extern char *index();
- extern char *rindex();
- extern long atol();
- extern char *dupfpath();
- extern char *strdup();
- extern char *multcat();
-
- char *get_route();
-
- LOCFUN auth_warn(), auth_ok(), auth_fetch(), auth_log();
-
-
- /*
- * Structures needed for by user authorization
- */
-
- /* values for user auth */
-
- #define AUTH_SEND 1 /* send only */
- #define AUTH_RECV 2 /* receive only */
- #define AUTH_BOTH 3 /* send + receive */
- #define AUTH_LIST 4 /* mailing list */
- #define AUTH_BAD -1 /* not authorized */
- #define AUTH_EXPIRE -2 /* authorization expired*/
-
- #define AUTH_NCHANS 15 /* max channels can have */
-
- struct auth_struct
- {
- int a_type; /* auth type */
- int a_nchans; /* number of channels */
- Chan *a_chans [AUTH_NCHANS];
- /* channel list */
- char *a_addr; /* the address */
- char *a_reason; /* rason for expiry */
- };
-
- LOCVAR
- struct auth_struct auth_sender, /* sender authorization */
- auth_rcvr; /* current receiver auth */
-
-
- LOCVAR
- int auth_do; /* is this mesage being authorized? */
- /* prevents logging on local and other */
- /* uninteresting traffic */
-
- LOCVAR
- char *route_in; /* route assocaited with incoming */
- /* address */
- LOCVAR
- char *route_out;
-
- LOCVAR
- char *cn_in, *cn_out; /* storage for channel names */
- /* needed for bad auth logging */
-
-
- /**/
- /* Authorization initialisation policy */
- /* Store data on sender */
-
- auth_init (sender, trust)
- char *sender; /* Message sender (normalized) */
- int trust; /* can we trust this? (NRMFROM) */
- {
- char *p;
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "auth_init (%s)", sender);
- #endif
-
- auth_sender.a_type = AUTH_BAD;
- auth_do = FALSE;
- /* SEK this is needed so that WARN/LOG */
- /* work correctly for host auth */
-
- if (alogptr -> ll_file[0] != '/')
- alogptr -> ll_file = dupfpath (alogptr -> ll_file, logdfldir);
-
- /* strip local domain for loocup */
- auth_sender.a_addr= strdup (sender);
- auth_sender.a_nchans = 0; /* make sure this has safe value */
- auth_sender.a_reason = (char *) 0;
-
- if (isstr(sender))
- route_in = get_route (sender);
- else
- route_in = (char *)0;
-
- if ((authtable = tb_nm2struct ("auth")) == (Table *) NOTOK)
- return;
-
- if ( auth_sender.a_addr && auth_sender.a_addr[0] != '@')
- {
- if ((p = index (auth_sender.a_addr, '@')) != (char *) 0)
- if (lexequ (p + 1, adr_fulldmn))
- *p = '\0';
- }
- /* Table exists, so look up sender */
- if (!trust && (adruid != 0))
- /* This can't be authorized */
- auth_sender.a_type = AUTH_BAD;
- else
- auth_fetch (&auth_sender);
- }
- /**/
- /* initialise user check, as user may be */
- /* checked in the context of a number of */
- /* channels */
- auth_uinit (adr)
- char *adr; /* address being authorized */
- {
- char *p,
- *q;
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "auth_uinit (%s)", adr);
- #endif
- auth_msg [0] = '\0';
- route_out = (char *) 0;
-
- if (authtable == (Table *) NOTOK)
- {
- auth_rcvr.a_addr = strdup (adr);
- auth_rcvr.a_type= AUTH_BAD;
- /* Assume no authorization as default */
- return;
- }
-
- /* this jiggling is to map local names */
- /* on other local machines to just */
- /* user names */
- /* e.g. ~foo@44c.ucl-cs.ac.uk -> foo */
- if (adr[0] != '@')
- {
- p = index (adr, '@');
- if (p != (char *) 0)
- {
- q = index (p + 1, '.');
- if (lexequ (p+1, adr_fulldmn) ||
- ((q != 0) && lexequ (q+1, adr_fulldmn)))
- {
- *p = '\0';
- if (adr[0] == '~')
- auth_rcvr.a_addr = strdup (&adr[1]);
- else
- auth_rcvr.a_addr = strdup (adr);
- *p= '@';
- }
- else
- auth_rcvr.a_addr = strdup (adr);
- }
- else
- auth_rcvr.a_addr = strdup (adr);
- }
- else
- auth_rcvr.a_addr = strdup (adr);
-
-
- /* Do not look up until needed - just mark */
- auth_rcvr.a_nchans = -1;
- auth_rcvr.a_reason = (char *) 0;
- }
-
- /* clean up user structures */
- auth_uend ()
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "auth_uend (), %d", authtable);
- #endif
- free (auth_rcvr.a_addr);
- if (authtable != (Table *) NOTOK)
- {
- if (auth_rcvr.a_reason != (char *) 0)
- free (auth_rcvr.a_reason);
- }
- if (route_out != (char *) 0)
- free (route_out);
- }
-
-
- /**/
- /* Perform checks for a given address */
- LOCVAR char *a_fmt = "i='%s' o='%s' a='%s' r='%s' r='%s'";
- LOCVAR char *h_fmt = "i='%s' o='%s' a='%s' r='%s' hi='%s' ho='%s'";
-
- #define AOKNUM 50
-
- auth_user (h_in, h_out, chan_in, chan_out)
- char *h_in; /* host (not domain) directly from */
- char *h_out; /* host (not domain) being connected to */
- Chan *chan_in; /* incoming channel */
- Chan *chan_out; /* outgoing channel */
- {
- char ch_in_auth; /* user auth needed for incomin chan */
- char ch_out_auth; /* ditto for outgoing chan */
- char in_hostanduser; /* flag if both host AND user auth needed */
- char out_hostanduser; /* flag if both host AND user auth needed */
- int gotinbound;
- int gotoutbound;
- char linebuf [LINESIZE];
- int argc;
- char *argv[AOKNUM];
- int ind;
- char *in_auth_str;
- char *out_auth_str;
- char *host_in;
- char *host_out;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "auth_user (hin='%s', hout='%s', cin='%s', cout='%s'",
- h_in, h_out, chan_in -> ch_show, chan_out -> ch_show);
- #endif
- ch_in_auth = chan_in -> ch_auth & CH_IN_AUTH;
- ch_out_auth = chan_out -> ch_auth & CH_OUT_AUTH;
-
- /* return immediately if no checks needed */
- if ((ch_in_auth == 0) && (ch_out_auth == 0))
- return (TRUE);
-
- cn_in = chan_in -> ch_name;
- cn_out = chan_out -> ch_name;
- in_hostanduser = FALSE;
- out_hostanduser = FALSE;
-
- if ((chan_out -> ch_auth & CH_DHO) == CH_DHO)
- {
- if (route_out == (char*) 0)
- route_out = get_route (auth_rcvr.a_addr);
- host_out = route_out;
- }
- else
- host_out = h_out;
-
- if ((chan_in -> ch_auth & CH_DHO) == CH_DHO)
- host_in = route_in;
- else
- host_in = h_in;
-
- if ((chan_out -> ch_auth & CH_HAU) == CH_HAU)
- out_hostanduser = TRUE;
- if ((chan_in -> ch_auth & CH_HAU) == CH_HAU)
- in_hostanduser = TRUE;
-
- /* initallialy check hostwise agreements */
- /* log any messages so authorized */
-
- /* 1 outbound host, ch_out */
- /* h_out:c_in/h_in */
- if (chan_out -> ch_outdest != (Table *) 0)
- {
- if (tb_k2val (chan_out -> ch_outdest, TRUE, host_out, linebuf)==OK)
- { /* this destination is listed */
- argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
- if (argc == 0) /* authorized for all senders */
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "OH", "", host_out);
- if (out_hostanduser)
- goto douser;
- return (TRUE);
- }
- for (ind = 0; ind < argc; ind++)
- /* all hosts on channel authorized? */
- if (lexequ (chan_in -> ch_name, argv[ind]))
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "CH", "", host_out);
- if (out_hostanduser)
- goto douser;
- return (TRUE); /* this pair is authorized */
- }
- for (ind = 0; ind < argc; ind++)
- /* host, itself, authorized? */
- if (lexequ (host_in, argv[ind]))
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "HH", host_in, host_out);
- if (out_hostanduser)
- goto douser;
- return (TRUE);
- }
- }
- }
-
- /* 2 inbound hosts, ch_in */
- /* h_in:c_out/h_out */
-
- if (chan_in -> ch_insource != (Table *) 0)
- {
- if (tb_k2val (chan_in -> ch_insource, TRUE, host_in, linebuf)==OK)
- { /* this destination is listed */
- argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
- if (argc == 0) /* authorized for all senders */
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "IH", host_in, "");
- if (in_hostanduser)
- goto douser;
- return (TRUE);
- }
- for (ind = 0; ind < argc; ind++)
- /* all hosts on channel authorized? */
- if (lexequ (chan_out -> ch_name, argv[ind]))
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "HC", host_in, "");
- if (in_hostanduser)
- goto douser;
- return (TRUE); /* this pair is authorized */
- }
- for (ind = 0; ind < argc; ind++)
- /* host, itself, authorized? */
- if (lexequ (host_out, argv[ind]))
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "HH", host_in, host_out);
- if (in_hostanduser)
- goto douser;
- return (TRUE);
- }
- }
- }
-
-
- /* 3 inbound hosts, ch_out */
- /* c_in:h_out */
- /* h_in:h_out */
-
-
- if (chan_out -> ch_outsource != (Table *) 0)
- {
- if (tb_k2val (chan_out -> ch_outsource, TRUE,
- chan_in -> ch_name, linebuf)==OK)
- { /* source channel is listed */
- argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
- if (argc == 0) /* authorized for all receivers */
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "CC", "", "");
- if (out_hostanduser)
- goto douser;
- return (TRUE);
- }
- for (ind = 0; ind < argc; ind++)
- if (lexequ (host_out, argv[ind]))
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "CH", "", host_out);
- if (out_hostanduser)
- goto douser;
- return (TRUE); /* this channel is authorized */
- }
- }
- if (tb_k2val (chan_out -> ch_outsource, TRUE,
- host_in, linebuf)==OK)
- { /* this source is listed */
- argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
- if (argc == 0) /* authorized for all receivers */
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "IH", host_in, "");
- if (out_hostanduser)
- goto douser;
- return (TRUE);
- }
- for (ind = 0; ind < argc; ind++)
- if (lexequ (host_out, argv[ind]))
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "HH", host_in, host_out);
- if (out_hostanduser)
- goto douser;
- return (TRUE); /* this pair is authorized */
- }
- }
- }
-
- /* 4, outbound hosts, ch_in */
- /* h_out:h_in */
- /* c_out:h_in */
-
- if (chan_in -> ch_indest != (Table *) 0)
- {
- if (tb_k2val (chan_in -> ch_indest, TRUE,
- chan_out -> ch_name, linebuf)==OK)
- { /* source channel is listed */
- argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
- if (argc == 0) /* authorized for all receivers */
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "CC", "", "");
- if (in_hostanduser)
- goto douser;
- return (TRUE);
- }
- for (ind = 0; ind < argc; ind++)
- if (lexequ (host_in, argv[ind]))
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "HC", host_in, "");
- if (in_hostanduser)
- goto douser;
- return (TRUE); /* this channel is authorized */
- }
- }
- if (tb_k2val (chan_in -> ch_indest, TRUE,
- host_out, linebuf)==OK)
- { /* this source is listed */
- argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
- if (argc == 0) /* authorized for all receivers */
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "OH", "", host_out);
- if (in_hostanduser)
- goto douser;
- return (TRUE);
- }
- for (ind = 0; ind < argc; ind++)
- if (lexequ (host_in, argv[ind]))
- {
- auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, "HH", host_in, host_out);
- if (in_hostanduser)
- goto douser;
- return (TRUE); /* this pair is authorized */
- }
- }
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "Checking auth: need in =%o out =%o",
- ch_in_auth, ch_out_auth);
- #endif
-
- if (in_hostanduser || out_hostanduser)
- {
- auth_log ("NO HOST AUTH i='%s' o='%s' s='%s' r='%s' msg='%s'",
- cn_in, cn_out, auth_sender.a_addr, auth_rcvr.a_addr, auth_msg);
- return (FALSE);
- }
-
-
- douser:
- in_auth_str = "";
- out_auth_str = "";
-
- if (ch_in_auth == 0)
- gotinbound = TRUE;
- else
- gotinbound = FALSE;
-
- if (ch_out_auth == 0)
- gotoutbound = TRUE;
- else
- gotoutbound = FALSE;
-
-
- /* lookup value if needed */
- if ((auth_rcvr.a_nchans < 0) && (authtable != (Table *) NOTOK))
- {
- auth_rcvr.a_nchans = 0;
- auth_fetch (&auth_rcvr);
- }
-
-
- /* now see if we can find any user authorization */
- /* if recipeint is authorized list, charge by pref */
- if (auth_rcvr.a_type == AUTH_LIST)
- {
- if (!gotinbound)
- if (gotinbound = auth_ok (chan_in, &auth_rcvr, AUTH_RECV))
- {
- in_auth_str = "IL";
- if (gotoutbound)
- {
- auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
- }
- if (!gotoutbound)
- if (gotoutbound = auth_ok (chan_out, &auth_rcvr, AUTH_RECV))
- {
- out_auth_str ="OL";
- if (gotinbound)
- {
- auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
- }
- }
- /* Now check sender */
- if (!gotinbound)
- if (gotinbound = auth_ok (chan_in, &auth_sender, AUTH_SEND))
- {
- in_auth_str = "IS";
- if (gotoutbound)
- {
- auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
- }
- else if (auth_rcvr.a_type == AUTH_LIST)
- switch (ch_in_auth)
- {
- case CH_IN_BLOCK:
- return (FALSE);
- case CH_IN_WARN:
- auth_warn ();
- default:
- in_auth_str = "*I";
- if (gotoutbound)
- {
- auth_log (a_fmt, chan_in -> ch_name,
- chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
- gotinbound = TRUE;
- }
-
- if (!gotoutbound)
- if (gotoutbound = auth_ok (chan_out, &auth_sender, AUTH_SEND))
- {
- out_auth_str ="OS";
- if (gotinbound)
- {
- auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
- }
- else if (auth_rcvr.a_type == AUTH_LIST)
- switch (ch_out_auth)
- {
- case CH_OUT_BLOCK:
- return (FALSE);
- case CH_OUT_WARN:
- auth_warn ();
- default:
- out_auth_str = "*O";
- auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
-
- /* if not done aready, check receiver */
- if (auth_rcvr.a_type == AUTH_LIST)
- return (FALSE);
-
-
- if (!gotinbound)
- if (gotinbound = auth_ok (chan_in, &auth_rcvr, AUTH_RECV))
- {
- in_auth_str = "IR";
- if (gotoutbound)
- {
- auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
- }
- else
- switch (ch_in_auth)
- {
- case CH_IN_BLOCK:
- return (FALSE);
- case CH_IN_WARN:
- auth_warn ();
- default:
- in_auth_str = "*I";
- if (gotoutbound)
- {
- auth_log (a_fmt, chan_in -> ch_name,
- chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
- gotinbound = TRUE;
- }
-
- if (!gotoutbound)
- if (gotoutbound = auth_ok (chan_out, &auth_rcvr, AUTH_RECV))
- {
- out_auth_str = "OR";
- if (gotinbound)
- {
- auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, out_auth_str);
- return (TRUE);
- }
- }
- else
- switch (ch_out_auth)
- {
- case CH_OUT_BLOCK:
- return (FALSE);
- case CH_OUT_WARN:
- auth_warn ();
- default:
- auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
- auth_rcvr.a_addr, in_auth_str, "*O");
- return (TRUE);
- }
-
- /* SEK shouldn't get here - I hope */
- #ifdef DEBUG
- ll_log (logptr, LLOGTMP, "Auth_user - did the impossible");
- #endif
- return (FALSE);
- }
- /**/
- LOCFUN auth_warn ()
- {
- FILE *fp;
- char buf [LINESIZE];
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "auth_warn ()");
- #endif
- if (!isstr(mgt_return))
- return;
- sprintf (buf, "Authorization Warning Daemon <%s>", authrequest);
- ml_1adr (NO, YES, buf, "Authorization Warning",
- mgt_return);
- ml_txt ("\nNot authorized to send mail to address: ");
- ml_txt (auth_rcvr.a_addr);
- ml_txt ("\n\n");
- if ((fp = fopen (authfile, "r")) == 0)
- {
- ml_txt ("Message sent anyhow\n\n");
- ll_log (logptr, LLOGTMP, "Auth warning file '%s' not found",
- authfile);
- }
- else
- ml_file (fp);
- if (ml_end (OK) != OK)
- ll_log (logptr, LLOGTMP, "Failed to send auth warning to '%s'",
- auth_sender.a_addr);
- }
- /**/
- /* what to do if bad address */
- auth_bad ()
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "auth_bad()");
- #endif
- /* build string for submit to pass up */
- if (auth_sender.a_type == AUTH_EXPIRE)
- {
- if (auth_sender.a_reason == (char *) 0)
- sprintf (auth_msg, "sender '%s' no longer authorized for address '%s'",
- auth_sender.a_addr, auth_rcvr.a_addr);
- else
- sprintf (auth_msg, "sender '%s' no authorization for address '%s' for reason: (%s)",
- auth_sender.a_addr,
- auth_rcvr.a_addr,
- auth_sender.a_reason);
- }
- else if (auth_rcvr.a_type == AUTH_EXPIRE)
- {
- if (auth_rcvr.a_reason == (char *) 0)
- sprintf (auth_msg, "recipient '%s' no longer authorized",
- auth_rcvr.a_addr);
- else
- sprintf (auth_msg, "recipient '%s' no authorization for reason: (%s)",
- auth_rcvr.a_addr,
- auth_rcvr.a_reason);
- }
- else
- #ifdef UCL
- sprintf (auth_msg, " Sender '%s' not authorized.",
- auth_sender.a_addr);
- #else /* UCL */
- sprintf (auth_msg, "sender '%s' not authorized to send to address '%s'",
- auth_sender.a_addr, auth_rcvr.a_addr);
- #endif /* UCL */
-
- auth_log ("BAD AUTH i='%s' o='%s' s='%s' r='%s' msg='%s'",
- cn_in, cn_out, auth_sender.a_addr, auth_rcvr.a_addr, auth_msg);
- #ifdef UCL
- strcat (auth_msg, " Mail ");
- strcat (auth_msg, authrequest);
- strcat (auth_msg, " (with an empty message) for help.");
- #else /* UCL */
- strcat (auth_msg, " : send queries to ");
- strcat (auth_msg, authrequest);
- #endif
- }
-
-
- /**/
- /* Perform any authorization ending policy */
-
- auth_end ()
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "auth_end()");
- #endif
- if (auth_do)
- auth_log ("END size='%ld', sender='%s'", tx_msize, auth_sender.a_addr);
- if (auth_sender.a_addr != (char *)0)
- free (auth_sender.a_addr);
- if (auth_sender.a_reason != (char *) 0)
- free (auth_sender.a_reason);
- if (route_in != (char *)0)
- free (route_in);
- }
-
- /**/
-
- /* check if chan matches auth */
- LOCFUN
- auth_ok (chan, auth, direction)
- Chan *chan;
- struct auth_struct *auth;
- int direction; /* send or receive */
- {
- int i;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "auth_ok (c='%s', u='%s', d='%s')",
- chan -> ch_name, auth -> a_addr,
- (direction == AUTH_RECV) ? "receive" : "send");
- #endif
-
- if (auth -> a_type < 0)
- return (FALSE);
-
- if (direction == AUTH_RECV)
- {
- switch (auth -> a_type)
- {
- case AUTH_SEND:
- return (FALSE);
- }
- }
- else
- {
- switch (auth -> a_type)
- {
- case AUTH_RECV:
- case AUTH_LIST:
- return (FALSE);
- }
- }
-
- for (i = 0; i < auth -> a_nchans; i++)
- if (chan == auth -> a_chans [i])
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "Got valid authorization");
- #endif
- return (TRUE);
- }
- return (FALSE);
- }
-
- /**/
-
- LOCVAR Cmd
- authmap [] =
- {
- "both", AUTH_BOTH, 0,
- "send", AUTH_SEND, 0,
- "recv", AUTH_RECV, 0,
- "list", AUTH_LIST, 0,
- "expire", AUTH_EXPIRE, 0,
- 0, 0, 0,
- };
-
-
- /* Get user authorization from table */
- LOCFUN
- auth_fetch (auth)
- struct auth_struct *auth; /* where to put the data */
- {
- char buf [LINESIZE];
- char *argv [AUTH_NCHANS + 1];
- int i,
- argc;
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "auth_fetch (%s)", auth -> a_addr);
- #endif
- /* implictly auth table exists */
- if (tb_k2val (authtable, TRUE, auth -> a_addr, buf)!=OK)
- {
- auth -> a_type = AUTH_BAD;
- return;
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "user '%s' has auth '%s'", auth -> a_addr, buf);
- #endif
- /* authorization ha form of type */
- /* followed by a list of channels */
- if ((argc = str2arg (buf, AUTH_NCHANS + 1, argv, (char *) 0))
- == NOTOK)
- {
- ll_log (logptr, LLOGTMP, "User '%s' has more that %d chans",
- auth -> a_addr, AUTH_NCHANS);
- auth -> a_type = AUTH_BAD;
- return;
- }
- /* get auth type */
- switch (auth -> a_type = cmdsrch (argv[0], 0, authmap))
- {
- case AUTH_BOTH:
- case AUTH_SEND:
- case AUTH_RECV:
- case AUTH_LIST:
- break;
- case AUTH_EXPIRE:
- break;
- default:
- auth -> a_type = AUTH_EXPIRE;
- auth -> a_reason = strdup (argv [0]);
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "User '%s' expire reason '%s'",
- auth -> a_addr, argv[0]);
- #endif
- break;
- }
-
-
- /* now fill in the chans */
- auth -> a_nchans = 0;
- for (i = 1; i < argc; i++)
- {
- if ((auth -> a_chans [auth -> a_nchans] = ch_nm2struct (argv[i]))
- == (Chan *) NOTOK)
- ll_log (logptr, LLOGBTR,
- "Unknown channel name '%s' for user '%s'", argv[i], auth -> a_addr);
- else
- auth -> a_nchans++;
- }
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "%d channels in total type = %d",
- auth -> a_nchans, auth -> a_type);
- #endif
- }
-
- /**/
-
- /* this loggin might be done differnetly */
- /* later */
-
- extern char *mq_munique;
-
- /* Log authorization info */
- /*VARARGS1*/
- LOCFUN
- auth_log (format, a1, a2, a3, a4, a5, a6, a7, a8, a9)
- char *format,
- *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9;
- {
- char fbuf [LINESIZE];
-
- auth_do = TRUE; /* we now care about this message */
- sprintf (fbuf, "%%s: %s", format);
- ll_log (&authlog, LLOGFST, fbuf, mq_munique, a1, a2, a3, a4, a5,
- a6, a7, a8, a9);
- }
-
- /**/
-
- /*
- * get_route is used to determine the route assocaited with
- * a given address. This allows authorization on the whole
- * route and not just the connect host.
- * It works by:
- * 1) breaking the address into parts
- * 2) remove the username from the local part, assiming a mix of percent
- * and UUCP routes.
- * The username starts right of the rightmost "!", and is
- * terminated by "%".
- * 3) Put it all back together again
- */
- char *get_route (adr)
- char *adr;
- {
- char *p, *q, *r;
- AP_ptr local, /* pointers for parse coponents */
- domain,
- route;
- AP_ptr ap;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "get_route (%s)", adr);
- #endif
-
- ap = ap_s2tree (adr);
-
- ap_t2parts (ap, (AP_ptr *) 0, (AP_ptr *) 0, &local, &domain, &route);
-
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "local part = '%s'", local -> ap_obvalue);
- #endif
- /* jiggle the local part */
- if ((p = rindex (local -> ap_obvalue, '!')) == (char *) 0)
- {
- if ((p = index (local -> ap_obvalue, '%')) != (char *) 0)
- {
- q = multcat (p, user_string, (char *)0);
- free (local -> ap_obvalue);
- local -> ap_obvalue = q;
- }
- else
- {
- /* local part really sseems to be user */
- free (local -> ap_obvalue);
- local -> ap_obvalue = strdup (user_string);
- }
- }
- else
- {
- /* p points to last "!" */
- q = index (p, '%');
- p++;
- *p = '\0';
- if (q != (char *) 0)
- r = multcat (local -> ap_obvalue, user_string, q, (char *)0);
- else
- r = multcat (local -> ap_obvalue, user_string, (char *)0);
- *p = '%';
- free (local -> ap_obvalue);
- local -> ap_obvalue = r;
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "Munged local part = '%s'", local -> ap_obvalue);
- #endif
-
- p = ap_p2s ((AP_ptr) 0, (AP_ptr) 0, local, domain, route);
-
- ap_sqdelete (ap, (AP_ptr)0);
- ap_free (ap);
-
- #ifdef DEBUG
- ll_log (logptr,LLOGFTR, "Auth ROUTE is '%s'",(p==(char*)MAYBE)?"MAYBE":p);
- #endif
- return (p);
- }
-